﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Collections;
using System.Reflection;
using UMC.Web;
using UMC.Data.Entities;
using UMC.Web.UI;
using UMC.ITME.Entities;
using UMC.Data;
using UMC.Net;
using System.Text;

namespace UMC.ITME.Activities
{
    /// <summary>
    /// 应用管理
    /// </summary>
    [UMC.Web.Apiumc("ITME", "Site", Auth = WebAuthType.User)]
    public class SiteActivity : WebActivity
    {

        static void Feilds(Hashtable hashtable, String key)
        {
            var feilds = hashtable["Feilds"] as Hashtable;
            if (feilds != null)
            {

                var fd = feilds.Keys.Cast<String>().OrderBy(r => r).GetEnumerator();

                while (fd.MoveNext())
                {
                    var pconfig = UMC.Data.DataFactory.Instance().Config(key + "_" + fd.Current.ToUpper())?.ConfValue ?? StringValue.Empty;
                    if (pconfig.Length > 0)
                    {
                        var feld = JSON.Deserialize<Hashtable>(pconfig.UTF8());
                        feld["Caption"] = feilds[fd.Current];
                        feilds[fd.Current] = feld;
                    }
                    else
                    {
                        var feld = new Hashtable();
                        feld["Caption"] = feilds[fd.Current];
                        feilds[fd.Current] = feld;
                    }
                }
            }
        }
        void Market(Site site)
        {

            var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
            if (String.IsNullOrEmpty(secret))
            {
                this.Context.Response.Redirect("System", "License", new UIConfirmDialog("当前版本未登记注册") { DefaultValue = "Select" });
            }
            if (((site.Flag ?? 0) & 2) == 2)
            {
                this.Prompt("提示", "此是从发布市场安装的应用,不能再提到应用市场");
            }
            if (String.IsNullOrEmpty(site.MarketKey) == false)
            {
                this.Prompt("提示", "不能发布来源于市场的应用");
            }
            if (site.IsMarket ?? false == false)
            {
                var data = PutMarket(site, secret);
                if (String.Equals(data?["code"], "success"))
                {
                    DataFactory.Instance().Put(new Site { IsMarket = true, Root = site.Root });
                }
                else
                {
                    this.Prompt(data?["msg"]);
                }

            }
            this.Context.Response.Redirect("ITME", "Market", site.Root);
        }
        public static WebMeta PutMarket(Site site, string secret)
        {
            var confData = new Hashtable();
            Reflection.PropertyToDictionary(site, confData);
            confData.Remove("AdminConf");
            confData.Remove("AppendJSConf");
            confData.Remove("AppSecret");
            confData.Remove("AppSecretAuth");
            confData.Remove("MarketKey");
            confData.Remove("ImagesConf");
            confData.Remove("IsModule");
            confData.Remove("IsAuth");
            confData.Remove("IsDebug");
            confData.Remove("IsMarket");
            confData.Remove("ModifyTime");
            confData.Remove("IsDesktop");
            confData.Remove("SiteKey");
            confData.Remove("HostModel");
            confData.Remove("Conf");
            confData.Remove("Seq");
            confData.Remove("GroupKey");
            confData.Remove("Type");
            confData.Remove("MarketKey");


            var configSite = new SiteConfig(site);
            if (configSite.IsForwardProxy)
            {
                var proxySites = HotCache.Find(new ProxySite());
                var hash = new Hashtable();
                var pkey = site.SiteKey.Value.StringValue().Span;
                foreach (var proxy in proxySites)
                {
                    if (proxy.ConfigKey.Contains(pkey))
                    {
                        if (proxy.Type.Int32() == 1)
                        {
                            var bs = new byte[proxy.ProxyIP.Length + 1];
                            proxy.ProxyIP.Span.CopyTo(bs);
                            bs[proxy.ProxyIP.Length] = 0x01;
                            hash[proxy.Domain.UTF8()] = Utility.ToBase64String(bs);//proxy.ProxyType.Span);
                        }
                        else
                        {
                            hash[proxy.Domain.UTF8()] = Utility.ToBase64String(proxy.ProxyIP.Span);

                        }
                    }
                }
                confData["proxy"] = hash;
            }
            else
            {
                var login = UMC.Data.DataFactory.Instance().Config($"SITE_MIME_{site.Root}_LOGIN".ToUpper())?.ConfValue ?? StringValue.Empty;
                if (login.Length > 0)
                {
                    var hash = JSON.Deserialize<Hashtable>(login.UTF8());
                    Feilds(hash, $"SITE_MIME_{site.Root}_LOGIN".ToUpper());
                    confData["login"] = hash;
                }

                login = UMC.Data.DataFactory.Instance().Config($"SITE_MIME_{site.Root}_CHECK".ToUpper())?.ConfValue ?? StringValue.Empty;
                if (login.Length > 0)
                {
                    var hash = JSON.Deserialize<Hashtable>(login.UTF8());
                    Feilds(hash, $"SITE_MIME_{site.Root}_CHECK".ToUpper());
                    confData["check"] = hash;
                }
                login = UMC.Data.DataFactory.Instance().Config($"SITE_MIME_{site.Root}_UPDATE".ToUpper())?.ConfValue ?? StringValue.Empty;
                if (login.Length > 0)
                {
                    var hash = JSON.Deserialize<Hashtable>(login.UTF8());
                    Feilds(hash, $"SITE_MIME_{site.Root}_UPDATE".ToUpper());
                    confData["update"] = hash;
                }
                login = UMC.Data.DataFactory.Instance().Config($"SITE_MIME_{site.Root}_LOGIN_HTML".ToUpper())?.ConfValue ?? StringValue.Empty;
                if (login.Length > 0)
                {
                    confData["loginHtml"] = login.UTF8();
                }
                login = UMC.Data.DataFactory.Instance().Config($"SITE_RES_BLOCK_{site.Root}".ToUpper())?.ConfValue ?? StringValue.Empty;
                if (login != null)
                {
                    confData["resblock"] = login.UTF8();
                }

                var appendJSConf = SiteConfig.Config(site.AppendJSConf);
                var appendConf = new Hashtable();
                foreach (var append in appendJSConf)
                {
                    var md5Key = SiteActivity.MD5(append);
                    var config = UMC.Data.DataFactory.Instance().Config(String.Format("SITE_JS_CONFIG_{0}{1}", site.Root, md5Key).ToUpper())?.ConfValue ?? StringValue.Empty;
                    if (config.Length > 0)
                    {
                        appendConf[append] = config.UTF8();
                    }
                }
                if (appendConf.Count > 0)
                {
                    confData["appendJsConf"] = appendConf;
                }
                appendJSConf = SiteConfig.Config(site.ImagesConf);
                var confImage = new Hashtable();
                foreach (var append in appendJSConf)
                {
                    var md5Key = SiteActivity.MD5(append);
                    var config = UMC.Data.DataFactory.Instance().Config($"SITE_IMAGE_CONFIG_{site.Root}{md5Key}".ToUpper())?.ConfValue ?? StringValue.Empty;
                    if (config.Length > 0)
                    {
                        confImage[append] = config.UTF8();
                    }
                }
                if (confImage.Count > 0)
                {
                    confData["confImage"] = confImage;
                }
            }
            // if(proxySite.)
            var data = JSON.Deserialize<WebMeta>(UMC.ITME.Utility.Sign(new Uri(APIProxy.Uri, "Transfer").WebRequest(), secret).Put(new WebMeta().Put("type", "AppGoods").Put("value", confData), out var _));
            return data;

        }
        public void ResBlockPage(Site site)
        {
            var configKey = $"SITE_RES_BLOCK_{site.Root}".ToUpper();
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "响应转化" };

                from.AddTextarea("响应路径配对", "Value", UMC.Data.DataFactory.Instance().Config(configKey)?.ConfValue?.UTF8()).Put("Pre", true).Put("Rows", 20).NotRequired();
                from.AddFooter("字典对格式,多项换行;值分为单值和双值格式,单值是nodejs文件则由nodejs转化输出,否则检索此单值来触发登录;双值则是检索尾值内容来触发跳转，无值项，则是触发登录页");
                from.Submit("确认", "Site.Config");
                return from;
            });
            String Value = config["Value"] ?? String.Empty;
            UMC.Data.DataFactory.Instance().Put(new Config { ConfKey = configKey, ConfValue = new StringValue(Value.UTF8()) });
            this.Context.Send("Site.Config", true);
        }

        public void OutputCookie(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "会话设置" };
                from.AddTextarea("Cookie名称", "OutputCookie", site.OutputCookies).Put("Pre", true).PlaceHolder("Cookie的名称和路径").NotRequired();
                from.AddFooter("设置与客户端共享的Cookie。");
                from.Submit("确认", "Site.Config");
                return from;
            });
            String OutputCookie = config["OutputCookie"] ?? String.Empty;

            DataFactory.Instance().Put(new Site { OutputCookies = OutputCookie, Root = site.Root });
            this.Context.Send("Site.Config", true);
        }
        public void Delete(Site site)
        {

            this.AsyncDialog("Config", g =>
             {
                 return new Web.UIConfirmDialog("您确认移除此应用吗") { Title = "移除提示" };
             });
            if (site.IsModule != true)
            {
                this.Prompt("请先把应用设置为隐藏应用，再来删除");
            }

            this.Context.Loger.Info().Write($"删除了应用{site.Root}").End();
            DataFactory.Instance().Put(new Site { Flag = -1, Root = site.Root, GroupKey = 0 });

            this.Context.Send("Site.Config", true);
        }

        public void Path(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "新增应用目录" };
                from.AddText("目录", "Path", String.Empty).PlaceHolder("以/开始的路径");
                from.AddText("应用", "Value", String.Empty);
                from.Submit("确认", "Site.Config");
                from.AddFooter("当目录最后为字符为“*”时,表示取后面的路径为子应用的请求路径");
                return from;
            });
            var Key = config["Path"];
            if (Key.StartsWith("/") == false)
            {
                this.Prompt("虚拟目录需要以/开头");
            }
            var Value = config["Value"];
            var site2 = DataFactory.Instance().Site(Value);
            if (site2 == null)
            {
                this.Prompt("未找到此标志的应用");
            }
            var path = new Hashtable();

            if (String.IsNullOrEmpty(site.SubSite) == false)
            {
                var v = UMC.Data.JSON.Deserialize(site.SubSite) as Hashtable;
                if (v != null)
                {
                    path = v;
                }
            }
            path[Key] = Value;
            site.SubSite = UMC.Data.JSON.Serialize(path);
            DataFactory.Instance().Put(new Site
            {
                Root = site.Root,
                SubSite = site.SubSite
            });

            this.Context.Send("Site.Config", true);
        }
        void TimeOut(Site site)
        {
            var config = this.AsyncDialog("TimeOut", g =>
            {
                var from = new Web.UIFormDialog() { Title = "应用时效" };
                from.AddNumber("请求超时", "Timeout", site.Timeout).PlaceHolder("单位为秒，默认10秒");
                from.AddNumber("登录过期", "AuthExpire", site.AuthExpire).PlaceHolder("单位为分,默认30分钟");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Timeout = UMC.Data.Utility.IntParse(config["Timeout"], 100);
            var AuthExpire = UMC.Data.Utility.IntParse(config["AuthExpire"], 0);
            if (Timeout <= 0 || AuthExpire < 0)
            {
                this.Prompt("时间不能小于零");
            }

            DataFactory.Instance().Put(new Site { Root = site.Root, AuthExpire = AuthExpire, Timeout = Timeout });
            this.Context.Send("Site.Config", true);
        }
        void HeaderConf(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "请求配置" };
                if (String.IsNullOrEmpty(site.MarketKey) == false)
                {
                    var lic = License.GetLicense(site.MarketKey.Split('_')[0]);
                    from.Add(UICell.UI("编辑证书", Utility.Expire(Utility.TimeSpan(), lic.ExpireTime, "已过期"), new UIClick(this.Context.Request, "Model", "EditCert")));
                }
                from.AddTextarea("请求头配置", "HeaderConf", site.HeaderConf).Put("Pre", true).PlaceHolder("字典配置格式").Put("Rows", 8).NotRequired();
                from.AddFooter("将会追加请求的Header上，当值为HOST、SCHEME、ADDRESS将会分别替换成当前值，当格式以=分割时，则表示此值追加到Cookie上");

                from.Submit("确认", "Site.Config");

                return from;
            });
            var HostReConf = config["HeaderConf"] ?? String.Empty;


            DataFactory.Instance().Put(new Site { Root = site.Root, HeaderConf = HostReConf });
            this.Context.Send("Site.Config", true);
        }
        void HighFrequency(Site site)
        {
            var configKey = $"SITE_HIGHFREQUENCY_{site.Root}".ToUpper();
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "高频API" };

                from.AddTextarea("路径", "Value", UMC.Data.DataFactory.Instance().Config(configKey)?.ConfValue?.UTF8()).Put("Pre", true).Put("Rows", 20).NotRequired();
                from.AddFooter("设置后，相关路径将关闭Api攻击防护");
                from.Submit("确认", "Site.Config");
                return from;
            });
            String Value = config["Value"] ?? String.Empty;
            UMC.Data.DataFactory.Instance().Put(new Config { ConfKey = configKey, ConfValue = new StringValue(Value.UTF8()) });
            this.Context.Send("Site.Config", true);

        }
        void HostReConf(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "域名清洗" };
                from.AddTextarea("清洗路径", "HostReConf", site.HostReConf).Put("Pre", true).PlaceHolder("字典配置格式").Put("Rows", 8).NotRequired();
                from.AddFooter("格式为[路径标识] [in] [域名...] 默认响应内容的域名清洗，in表示请求内容的域名清洗 none表示不清洗");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var HostReConf = config["HostReConf"];


            DataFactory.Instance().Put(new Site { Root = site.Root, HostReConf = HostReConf });
            this.Context.Send("Site.Config", true);
        }
        void LogoutPath(Site site)
        {
            var sValue = this.AsyncDialog("Settings", g =>
            {
                var from2 = new UIFormDialog() { Title = "触发跳转" };
                from2.AddTextarea("触发路径", "LogoutPath", site.LogoutPath as string).Put("Pre", true).Put("Rows", 20).NotRequired();

                from2.AddFooter("字典对格式,多项用换行;结尾是“*”、“$”分别表示向前、向后比对路径;无值则是触发登录页,以@开头路径则表示自动登录后再请求，其它为跳转页");
                from2.Submit("确认", "Site.Config");
                return from2;
            })["LogoutPath"] ?? String.Empty;

            DataFactory.Instance().Put(new Site
            {
                LogoutPath = sValue,
                Root = site.Root
            });
            this.Context.Send("Site.Config", true);
        }
        void GroupKey(Site site)
        {
            var groupKey = Utility.IntParse(this.AsyncDialog("GroupKey", this.Context.Request.Model, "Group"), 0);

            DataFactory.Instance().Put(new Site { Root = site.Root, GroupKey = groupKey });

            this.Context.Send("Site.Config", true);
        }
        void Caption(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UITextDialog(site.Caption) { Title = "应用名称", CloseEvent = "Site.Config" };
                return from;
            });

            DataFactory.Instance().Put(new Site { Root = site.Root, Caption = config });
            this.Context.Send("Site.Config", true);
        }
        void AppSecret(Site site)
        {
            var config = UIDialog.AsyncDialog(this.Context, "AppSecret", g =>
            {
                var AppSecretAuth = site.AppSecretAuth ?? 0;
                var from = new Web.UIFormDialog() { Title = "应用安全码" };
                from.AddCheckBox("访问权限", "AppSecret", "0").Put("单点登录", "1", (AppSecretAuth & 1) > 0).Put("创建令牌", "2", (AppSecretAuth & 2) > 0);
                from.Submit("确认修改");
                from.Add(UICell.UI("显示安全码", "", new UIClick(this.Context.Request, g, "View")));
                from.Add(UICell.UI("重置安全码", "", new UIClick(this.Context.Request, g, "Reset")));
                from.Add(UICell.UI("随机重置", "", new UIClick(this.Context.Request, g, "Round")));
                return from;
            });
            switch (config)
            {

                case "Round":

                    this.AsyncDialog("Confim", g => new Web.UIConfirmDialog("随机重置后，历史安全码将不可用，确认吗"));
                    site.AppSecret = Utility.Guid(Guid.NewGuid());
                    DataFactory.Instance().Put(new Site { Root = site.Root, AppSecret = site.AppSecret });
                    this.Prompt("应用安全码", "AppSecret：" + site.AppSecret);
                    break;
                case "Reset":
                    var Value = UIDialog.AsyncDialog(this.Context, "Value", g =>
                    {
                        var from = new Web.UIFormDialog() { Title = "重置安全码" };
                        from.AddText("安全码", "Value", string.Empty);
                        from.AddFooter("重置后，当前安全码将不可用");
                        return from;
                    });
                    DataFactory.Instance().Put(new Site { Root = site.Root, AppSecret = Value });
                    break;
                case "View":
                    this.Prompt("应用安全码", "AppSecret：" + site.AppSecret);
                    break;
                default:
                    var AppSecret = 0;
                    foreach (var v in config.Split(','))
                    {
                        AppSecret |= Utility.IntParse(v, 0);
                    }
                    DataFactory.Instance().Put(new Site { Root = site.Root, AppSecretAuth = AppSecret });
                    break;
            }

        }

        void Setting(Site site)
        {
            var req = this.Context.Request;
            var config = this.AsyncDialog("Config", g =>
            {
                var ui = UISection.Create(new UITitle("应用设置"));
                var from = new Web.UIFormDialog() { Title = "应用设置" };
                ui.AddCell("应用主页", site.Home, new UIClick(req, g, "Home"));
                ui.AddCell("移动主页", site.MobileHome, new UIClick(req, g, "MobileHome"));


                switch (site.AuthType ?? WebAuthType.All)
                {
                    case WebAuthType.All:
                        ui.NewSection().AddCell("访问许可", "所有人", new UIClick(req, g, "AuthType"));
                        break;
                    case WebAuthType.Guest:
                        ui.NewSection().AddCell("访问许可", "登录人员", new UIClick(req, g, "AuthType"));
                        break;
                    case WebAuthType.Check:
                        ui.NewSection().AddCell("访问许可", "登录检查", new UIClick(req, g, "AuthType"));
                        break;
                    case WebAuthType.User:
                        ui.NewSection().AddCell("访问许可", "内部用户", new UIClick(req, g, "AuthType"));
                        break;
                    case WebAuthType.UserCheck:
                        ui.NewSection().AddCell("访问许可", "用户检查", new UIClick(req, g, "AuthType"));
                        break;
                    case WebAuthType.Admin:
                        ui.NewSection().AddCell("访问许可", "管理员", new UIClick(req, g, "AuthType"));
                        break;
                }

                ui.NewSection()//.Add(new UISwitch().Text("桌面展示").Selected(site.IsDesktop == true).Click(new UIClick(req, g, "NotDesktop"), new UIClick(req, g, "Desktop")))
                .Add(new UISwitch().Text("隐藏应用").Selected(site.IsModule == true).Click(new UIClick(req, g, "NotModule"), new UIClick(req, g, "Moduled")));

                ui.NewSection().Add(new UISwitch().Text("开启日志").Selected(site.IsDebug == true).Click(new UIClick(req, g, "NotDebug"), new UIClick(req, g, "Debug")))
                .Add(new UISwitch().Text("强化验证").Selected(site.IsAuth == true).Click(new UIClick(req, g, "NotAuth"), new UIClick(req, g, "Auth")));

                var userBrowser = site.UserBrowser ?? Entities.UserBrowser.All;

                var sb = new HashSet<String>();
                if (userBrowser.HasFlag(UserBrowser.IE))
                {
                    sb.Add("IE");
                }
                if (userBrowser.HasFlag(UserBrowser.Chrome))
                {
                    sb.Add("Chrome");
                }

                if (userBrowser.HasFlag(UserBrowser.Firefox))
                {
                    sb.Add("Firefox");
                }
                if (userBrowser.HasFlag(UserBrowser.Dingtalk))
                {
                    sb.Add("Dingtalk");
                }
                if (userBrowser.HasFlag(UserBrowser.WeiXin))
                {
                    sb.Add("WeiXin");
                }

                var OpenModel = "新窗口";
                switch (site.OpenModel ?? 0)
                {
                    case 1:
                        OpenModel = "当前窗口";
                        break;
                    case 2:
                        OpenModel = "最大化窗口";
                        break;
                    case 3:
                        OpenModel = "快捷方式";
                        break;
                }
                ui.NewSection().AddCell("打开方式", OpenModel, new UIClick(req, g, "OpenModel"))
                .AddCell("支持浏览器", sb.Count == 0 ? "不限浏览器" : String.Join(",", sb.ToArray()), new UIClick(req, g, "UserBrowser"));


                ui.NewSection().AddCell("缓存因子", site.Version, new UIClick(req, g, "Version"))
                    .AddCell("显示顺序", $"{site.Seq}", new UIClick(req, g, "Seq"));

                ui.NewSection()
                  .Add(new UISwitch().Text("开启正向代理").Selected(((site.Type ?? 0) & 2048) > 0).Click(new UIClick(req, g, "NotForwardProxy"), new UIClick(req, g, "ForwardProxy")));
                var pkey = site.SiteKey.Value.StringValue();


                var proxyUi = ui.NewSection().AddCell("正向代理", new UIClick(req, g, "AppendDomain"));
                var proxySites = HotCache.Find(new ProxySite());

                var proxyConfig = UMC.Data.Reflection.Configuration("proxy");
                foreach (var proxy in proxySites)
                {
                    if (proxy.ConfigKey.Contains(pkey.Span))
                    {
                        var domain = proxy.Domain.UTF8();
                        String proxyCaption = "默认节点";
                        var IPvalue = proxy.ProxyIP.UInt32() ?? 0;
                        if (IPvalue != 0)
                        {
                            var h = String.Join('.', IPvalue.StringValue().Span.ToArray());
                            var attr = proxyConfig[h];
                            if (attr == null)
                            {
                                proxyCaption = "外部节点";
                            }
                            else
                            {
                                proxyCaption = attr.Attributes["title"] ?? "默认节点";
                            }
                        }
                        else
                        {
                            proxyCaption = "默认节点";
                        }

                        var ui2 = UI.UI(domain, proxyCaption, new UIClick(req, "Domain", domain, g, "Domain"));

                        proxyUi.Delete(ui2, new UIEventText().Click(new UIClick(req, "Domain", domain, g, "Domain", "ProxyType", "Delete")));
                    }
                }

                ui.SendTo(this.Context, "Site.Setting");
            });
            switch (config)
            {
                case "AppendDomain":
                    {
                        var t = this.AsyncDialog("Domain", r =>
                        {
                            var dlg = new UIFormDialog() { Title = "附加代理域名" };
                            dlg.AddText("域名", "Domain", String.Empty);
                            var proxyConfig = UMC.Data.Reflection.Configuration("proxy");

                            var proxyType = dlg.AddRadio("代理节点", "ProxyType").Put("默认节点", "0", true);
                            foreach (var v in proxyConfig.Providers)
                            {
                                proxyType.Put(v["title"] ?? v["host"], v.Name);
                            }

                            return dlg;

                        });
                        var host = t["Domain"];
                        var ProxyType = 0;// Utility.IntParse(t["ProxyType"], 0);

                        int type = 0;
                        if (System.Net.IPAddress.TryParse(t["IP"], out var address))
                        {
                            ProxyType = new StringValue(address.GetAddressBytes()).Int32() ?? 0;
                            type = 1;
                        }
                        else if (System.Net.IPAddress.TryParse(t["ProxyType"], out address))
                        {
                            ProxyType = new StringValue(address.GetAddressBytes()).Int32() ?? 0;
                        }
                        if (System.Text.RegularExpressions.Regex.IsMatch(host, @"^([a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z0-9]{1,8}$") == false)
                        {
                            this.Prompt("域名格式不正确");
                        }
                        var proxySite = HotCache.Get(new ProxySite() { Domain = new StringValue(host) });
                        if (proxySite == null)
                        {
                            proxySite = new ProxySite { Domain = new StringValue(host), ConfigKey = site.SiteKey.Value.StringValue(), ProxyIP = ProxyType.StringValue(), Type = type.StringValue() };
                            HotCache.Put(proxySite);

                        }
                        else if (proxySite.ConfigKey.Contains(site.SiteKey.Value.StringValue().Span))
                        {
                            proxySite.ProxyIP = ProxyType.StringValue();
                            proxySite.Type = type.StringValue();
                            HotCache.Put(proxySite);

                            // Utility.SyncClient(3, new StringValue(host), ProxyType.StringValue(), new StringValue(new byte[] { (byte)type }));
                        }
                        else
                        {
                            var bus = new byte[proxySite.ConfigKey.Length + 4];
                            proxySite.ConfigKey.Span.CopyTo(bus);
                            BitConverter.TryWriteBytes(bus.AsSpan(proxySite.ConfigKey.Length), site.SiteKey.Value);// site.SiteKey.Value.StringValue().p
                            proxySite.ConfigKey = new StringValue(bus);
                            proxySite.ProxyIP = ProxyType.StringValue();
                            proxySite.Type = type.StringValue();
                            HotCache.Put(proxySite);
                        }
                        Utility.SyncClient(3, proxySite.Domain, proxySite.ProxyIP, new StringValue(new byte[] { (byte)type }));

                    }

                    break;
                case "Domain":
                    {
                        var host = this.AsyncDialog("Domain", "auth");
                        var proxySite = HotCache.Get(new ProxySite() { Domain = new StringValue(host) });

                        var ProxyType = UIDialog.AsyncDialog(this.Context, "ProxyType", r =>
                        {
                            var dlg = new UIFormDialog() { Title = "正向代理域名" };
                            dlg.AddTextValue().Put("域名", host);

                            var proxyConfig = UMC.Data.Reflection.Configuration("proxy");
                            var ipValue = proxySite.ProxyIP.Int32() ?? 0;
                            var proxyType = dlg.AddRadio("使用代理", "ProxyType");
                            proxyType.Put("默认节点", "0", ipValue == 0);

                            var ip4 = String.Join('.', ipValue.StringValue().Span.ToArray());
                            if (ipValue == 0 || proxyConfig.ContainsKey(ip4))
                            {
                                foreach (var v in proxyConfig.Providers)
                                {
                                    proxyType.Put(v["title"], v.Name, ip4 == v.Name);
                                }
                            }
                            else
                            {

                                proxyType.Clear();
                                proxyType.Put("外部节点", ip4, true);

                            }

                            dlg.AddCheckBox("", "Type", "0").Put("解析模式", "1", proxySite.Type.Int32() == 1);
                            var sb = new StringBuilder();

                            for (var i = 8; i <= proxySite.ProxyIP.Length; i += 4)
                            {
                                if (sb.Length > 0)
                                {
                                    sb.Append(',');
                                }
                                sb.Append(new System.Net.IPAddress(proxySite.ProxyIP.Slice(i - 4, 4).Span).ToString());
                            }

                            dlg.AddText("更多IP", "Server", sb.ToString()).NotRequired();
                            return dlg;
                        });

                        int sType = 0;

                        if (System.Net.IPAddress.TryParse(ProxyType, out var address))
                        {
                            sType = new StringValue(address.GetAddressBytes()).Int32() ?? 0;
                        }
                        if (proxySite == null)
                        {
                            if (ProxyType == "Delete")
                            {
                                this.Prompt("没有此域名");
                            }
                            else
                            {
                                proxySite = new ProxySite
                                {
                                    Domain = new StringValue(host),
                                    ConfigKey = site.SiteKey.Value.StringValue(),
                                    ProxyIP = sType.StringValue()
                                };
                                HotCache.Put(proxySite);
                                //   proxySite.ProxyIP
                                Utility.SyncClient(3, proxySite.Domain, proxySite.ProxyIP);

                            }
                        }
                        else
                        {


                            var siteKey = site.SiteKey.Value.StringValue();
                            switch (ProxyType)
                            {
                                case "Delete":
                                    var ConfigKey = proxySite.ConfigKey.Span;
                                    var b = ConfigKey.IndexOf(siteKey.Span);
                                    if (b > -1)
                                    {
                                        ConfigKey.Slice(b + 4).CopyTo(ConfigKey.Slice(b));
                                        if (ConfigKey.Length == 4)
                                        {
                                            HotCache.Delete(new ProxySite() { Domain = new StringValue(host) });

                                            Utility.SyncClient(3, new StringValue(host));
                                        }
                                        else
                                        {
                                            HotCache.Put(new ProxySite { Domain = proxySite.Domain, ConfigKey = new StringValue(ConfigKey.Slice(0, ConfigKey.Length - 4).ToArray()) });
                                        }
                                    }
                                    break;
                                default:

                                    var Servers = this.AsyncDialog("Server", "NO").Split(' ', ',');//.Contains("1") ? 1 : 0;

                                    var sbByte = new List<byte>();
                                    sbByte.AddRange(sType.StringValue().Span.ToArray());
                                    foreach (var s in Servers)
                                    {
                                        if (System.Net.IPAddress.TryParse(s, out var address1))
                                        {
                                            sbByte.AddRange(address1.GetAddressBytes());
                                        }
                                    }
                                    var IPtype = this.AsyncDialog("Type", "0").Contains("1") ? 1 : 0;
                                    proxySite.ProxyIP = new StringValue(sbByte.ToArray());
                                    if (proxySite.ConfigKey.Contains(site.SiteKey.Value.StringValue().Span))
                                    {
                                        // proxySite.ProxyIP = sType.StringValue();
                                        proxySite.Type = IPtype.StringValue();
                                        HotCache.Put(proxySite);
                                    }
                                    else
                                    {
                                        var bus = new byte[proxySite.ConfigKey.Length + 4];
                                        proxySite.ConfigKey.Span.CopyTo(bus);
                                        BitConverter.TryWriteBytes(bus.AsSpan(proxySite.ConfigKey.Length), site.SiteKey.Value);// site.SiteKey.Value.StringValue().p
                                        proxySite.ConfigKey = new StringValue(bus);
                                        // proxySite.ProxyIP = sType.StringValue();
                                        proxySite.Type = IPtype.StringValue();
                                        HotCache.Put(proxySite);
                                    }

                                    Utility.SyncClient(3, proxySite.Domain, proxySite.ProxyIP, new StringValue(new byte[] { (byte)IPtype }));
                                    break;
                            }
                        }

                    }
                    break;

                case "NotForwardProxy":
                    {
                        var type = site.Type ?? 0;
                        if ((type & 2048) > 0)
                            DataFactory.Instance().Put(new Site { Root = site.Root, Type = type ^ 2048 });

                        var proxySites = HotCache.Find(new ProxySite());
                        var siteKey = site.SiteKey.Value.StringValue();
                        if (proxySites.Any(r => r.ConfigKey.Contains(siteKey.Span)) == false)
                        {
                            var dms2 = site.Domain.Split(new char[] { '\n', ' ' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim()?.Replace("*.", "");

                            if (String.IsNullOrEmpty(dms2) == false)
                            {
                                var u = new Uri(dms2).Host;
                                this.Context.Send(new UIClick(req, "Config", "Domain", "Domain", new Uri(dms2).Host, "ProxyType", "-1"), true);
                            }
                        }
                    }
                    break;
                case "ForwardProxy":
                    {
                        DataFactory.Instance().Put(new Site { Root = site.Root, Type = (site.Type ?? 0) | 2048 });

                        var dms2 = site.Domain.Split(new char[] { '\n', ' ' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim()?.Replace("*.", "");

                        if (String.IsNullOrEmpty(dms2) == false)
                        {
                            this.Context.Send(new UIClick(req, "Config", "Domain", "Domain", new Uri(dms2).Host, "ProxyType", "0"), true);
                        }
                    }
                    break;
                case "NotDebug":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsDebug = false });
                    return;
                case "Debug":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsDebug = true });
                    return;
                case "Desktop":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsDesktop = true });
                    return;
                case "NotDesktop":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsDesktop = false });
                    return;
                case "Auth":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsAuth = true });
                    return;
                case "NotAuth":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsAuth = false });
                    return;
                case "Moduled":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsModule = true });
                    return;
                case "NotModule":
                    DataFactory.Instance().Put(new Site { Root = site.Root, IsModule = false });
                    return;
                case "Seq":
                    var Seq = this.AsyncDialog(config, r => new UINumberDialog(site.Seq) { Title = "显示顺序", CloseEvent = "Site.Setting" });

                    DataFactory.Instance().Put(new Site { Root = site.Root, Seq = Utility.IntParse(Seq, 0) });

                    break;
                case "Version":
                    var Version = this.AsyncDialog(config, r => new UITextDialog(site.Version) { Title = "缓存因子", CloseEvent = "Site.Setting" });

                    DataFactory.Instance().Put(new Site { Root = site.Root, Version = Version });

                    break;
                case "MobileHome":
                    var MobileHome = this.AsyncDialog(config, r => new UITextDialog(site.MobileHome) { Title = "移动主页", CloseEvent = "Site.Setting" });


                    if (MobileHome.StartsWith("https://") == false && MobileHome.StartsWith("http://") == false)
                    {
                        if (MobileHome.StartsWith("/") == false || MobileHome.StartsWith("//"))
                        {
                            this.Prompt("格式不正确");
                        }
                    }

                    DataFactory.Instance().Put(new Site { Root = site.Root, Home = MobileHome });
                    break;
                case "Home":
                    var Home = this.AsyncDialog(config, r => new UITextDialog("站点主页") { DefaultValue = site.Home, CloseEvent = "Site.Setting" });

                    if (Home.StartsWith("https://") == false && Home.StartsWith("http://") == false)
                    {
                        if (Home.StartsWith("/") == false || Home.StartsWith("//"))
                        {
                            this.Prompt("格式不正确");
                        }
                    }
                    DataFactory.Instance().Put(new Site { Root = site.Root, Home = Home });

                    break;
                case "UserBrowser":
                    var sUserBrowser = UIDialog.AsyncDialog(this.Context, "UserBrowser", r =>
                    {
                        var userBrowser = site.UserBrowser ?? Entities.UserBrowser.All;
                        var from = new Web.UIFormDialog() { Title = "支持浏览器" };
                        from.AddCheckBox("", "UserBrowser", "All")
                                     .Put("IE", "IE", (userBrowser & UserBrowser.IE) == UserBrowser.IE)
                                     .Put("谷歌", "Chrome", (userBrowser & UserBrowser.Chrome) == UserBrowser.Chrome)
                                     .Put("火狐", "Firefox", (userBrowser & UserBrowser.Firefox) == UserBrowser.Firefox)
                                     .Put("钉钉", "Dingtalk", (userBrowser & UserBrowser.Dingtalk) == UserBrowser.Dingtalk)
                                     .Put("微信", "WeiXin", (userBrowser & UserBrowser.WeiXin) == UserBrowser.WeiXin)
                                     .Put("WebKit", "WebKit", (userBrowser & UserBrowser.WebKit) == UserBrowser.WebKit);

                        return from;
                    });
                    var userBrowser2 = UserBrowser.All;
                    foreach (var v in sUserBrowser.Split(','))
                    {
                        userBrowser2 |= UMC.Data.Utility.Parse(v, UserBrowser.All);
                    }
                    DataFactory.Instance().Put(new Site { Root = site.Root, UserBrowser = userBrowser2 });
                    break;
                case "OpenModel":
                    var OpenModel = Utility.IntParse(this.AsyncDialog(config, r =>
                       {
                           return new UISheetDialog() { Title = "云桌面打开方式" }.Cells(2)
                   .Put("新窗口", "0")
                   .Put("当前窗口", "1")
                   .Put("最大化窗口", "2")
                   .Put("快捷方式", "3");
                       }), 0);
                    DataFactory.Instance().Put(new Site { Root = site.Root, OpenModel = OpenModel });
                    break;
                case "AuthType":

                    var AuthType = Utility.Parse(this.AsyncDialog(config, r =>
                       {
                           return new UISheetDialog() { Title = "访问许可" }.Cells(2)
                   .Put("所有人", "All")
                   .Put("登录人员", "Guest")
                   .Put("登录检查", "Check")
                   .Put("内部用户", "User")
                   .Put("用户检查", "UserCheck")
                   .Put("管理员", "Admin");
                       }), WebAuthType.All);
                    DataFactory.Instance().Put(new Site { Root = site.Root, AuthType = AuthType });

                    break;
            }
            this.Context.Send("Site.Setting", true);
        }
        public static string MD5(String src)
        {
            var md5 = System.Security.Cryptography.MD5.Create();
            byte[] md = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(src));
            return UMC.Data.Utility.Parse36Encode(UMC.Data.Utility.IntParse(md));
        }
        public void Share(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "设置共享模式" };
                var m = "标准模式";
                switch ((site.UserModel ?? UserModel.Standard))
                {
                    case UserModel.Bridge:
                        m = "桥接模式";
                        break;
                    case UserModel.Share:
                        m = "共享模式";
                        break;
                    case UserModel.Quote:
                        m = "引用模式";
                        break;
                    case UserModel.Check:
                        m = "自主检测";
                        break;
                    case UserModel.Checked:
                        m = "自动检测";
                        break;
                }
                from.AddTextValue().Put("当前模式", m);

                from.AddText("共享账户", "Account", site.Account).PlaceHolder("多账户可用|和~分割");

                from.AddText("共同密码", "Password", String.Empty);
                from.Submit("确认", "Site.Config");
                return from;
            });
            var acount = config["Account"];
            var pwd = config["Password"];

            var site2 = new Site()
            {
                Root = site.Root,
                Account = acount,
                UserModel = UserModel.Share
            };
            if (String.IsNullOrEmpty(pwd) == false)
            {
                UMC.Data.DataFactory.Instance().Password(SiteConfig.MD5Key(site.Root, acount), pwd);
            }
            DataFactory.Instance().Put(site2);
            this.Context.Send("Site.Config", true);
        }
        public void SetHostModel(Site site)
        {
            var config = this.AsyncDialog("HostModel", g =>
            {
                var from = new Web.UISheetDialog() { Title = "认证切换模式" };
                from.Put("不切换", "None").Put("登录页切换", "Login").Put("浏览器中切换", "Check")
                .Put("全域名切换", "Disable");

                return from;
            });
            var acount = UMC.Data.Utility.Parse(config, HostModel.None);
            DataFactory.Instance().Put(new Site
            {
                HostModel = acount,
                Root = site.Root
            });
            this.Context.Send("Site.Config", true);
        }
        public void UseModel(Site site)
        {
            var config = this.AsyncDialog("UserModel", g =>
            {
                var from = new Web.UISheetDialog() { Title = "设置账户模式" };

                from.Put("标准模式", "Standard").Put("桥接模式", "Bridge");
                var arg = this.Context.Request.Arguments;
                var m = this.Context.Request.Model;
                var c = this.Context.Request.Command;
                from.Put(new UIClick(m, c, new WebMeta(arg).Put("Model", "Quote")) { Text = "引用模式" });
                from.Put(new UIClick(m, c, new WebMeta(arg).Put("Model", "Share")) { Text = "共享模式" });


                return from;
            });
            var acount = UMC.Data.Utility.Parse(config, UserModel.Standard);
            DataFactory.Instance().Put(new Site
            {
                UserModel = acount,
                Root = site.Root
            });
            this.Context.Send("Site.Config", true);
        }
        public void Quote(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "设置引用模式" };
                var ak = "";
                if (String.IsNullOrEmpty(site.Account) == false && site.Account.StartsWith("@"))
                {
                    ak = site.Account.Substring(1);
                }
                var m = "标准模式";
                switch ((site.UserModel ?? UserModel.Standard))
                {
                    case UserModel.Bridge:
                        m = "桥接模式";
                        break;
                    case UserModel.Share:
                        m = "共享模式";
                        break;
                    case UserModel.Quote:
                        m = "引用模式";
                        break;
                    case UserModel.Check:
                        m = "自主检测";
                        break;
                    case UserModel.Checked:
                        m = "自动检测";
                        break;
                }
                from.AddTextValue().Put("当前模式", m);

                from.AddText("引用应用", "Account", ak);
                from.Submit("确认", "Site.Config");
                return from;
            });
            var acount = config["Account"];

            var site2 = DataFactory.Instance().Site(acount);
            if (site2 == null)
            {
                this.Prompt("未有引用的应用");
            }
            if (site2.Root == site.Root)
            {
                this.Prompt("引用应用不能配置自己");
            }
            switch (site2.UserModel ?? UserModel.Standard)
            {
                case UserModel.Standard:
                case UserModel.Share:
                case UserModel.Checked:
                case UserModel.Check:
                    break;
                default:
                    this.Prompt("应用不支持引用对接");
                    break;
            }
            DataFactory.Instance().Put(new Site
            {
                Account = "@" + acount,
                UserModel = UserModel.Quote,
                Root = site.Root
            });
            this.Context.Send("Site.Config", true);
        }
        public void Account(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "检测账户" };
                from.AddText("账户名称", "Account", site.Account);
                from.AddText("账户密码", "Password", String.Empty).NotRequired();
                from.Submit("确认", "Mime.Config");
                return from;
            });
            var acount = config["Account"];
            var pwd = config["Password"];

            var site2 = new Site()
            {
                Root = site.Root,
                Account = acount
            };
            if (String.IsNullOrEmpty(pwd) == false)
            {
                UMC.Data.DataFactory.Instance().Password(SiteConfig.MD5Key(site.Root, acount), pwd);
            }
            DataFactory.Instance().Put(site2);

            this.Context.Send("Mime.Config", true);
        }
        void Copy(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "复制应用" };

                from.AddText("新标识", "Root", String.Empty).PlaceHolder("[a-z0-9]全小写字符");

                from.AddText("新名称", "Caption", site.Caption);
                from.Submit("确认", "Site.Config");
                return from;
            });
            var newRoot = config["Root"].ToLower();
            if (System.Text.RegularExpressions.Regex.IsMatch(newRoot, "^[a-z0-9]+$") == false)
            {
                this.Prompt("应用标识只支持【a-z0-9】字符");
            }



            var oldSite = DataFactory.Instance().Site(newRoot);
            if (oldSite != null)
            {
                this.Prompt("此应用标识已注册");
            }


            CopyMime("SITE_MIME_{0}_LOGIN", site.Root, newRoot);
            CopyMime("SITE_MIME_{0}_CHECK", site.Root, newRoot);
            CopyMime("SITE_MIME_{0}_UPDATE", site.Root, newRoot);


            var jsPaths = SiteConfig.Config(site.AppendJSConf);
            foreach (var key in jsPaths)
            {
                var md5Key = MD5(key as string);
                var jsKey = String.Format("SITE_JS_CONFIG_{0}{1}", site.Root, md5Key).ToUpper();

                var pconfig = UMC.Data.DataFactory.Instance().Config(jsKey);
                if (pconfig != null)
                {
                    pconfig.ConfKey = String.Format("SITE_JS_CONFIG_{0}{1}", newRoot, md5Key).ToUpper();
                    UMC.Data.DataFactory.Instance().Put(pconfig);
                }
            }
            var Images = SiteConfig.Config(site.ImagesConf);
            foreach (var key in Images)
            {
                var md5Key = MD5(key as string);
                var jsKey = String.Format("SITE_IMAGE_CONFIG_{0}{1}", site.Root, md5Key).ToUpper();

                var pconfig = UMC.Data.DataFactory.Instance().Config(jsKey);
                if (pconfig != null)
                {
                    pconfig.ConfKey = String.Format("SITE_IMAGE_CONFIG_{0}{1}", newRoot, md5Key).ToUpper();
                    UMC.Data.DataFactory.Instance().Put(pconfig);
                }
            }


            var htmlconfig = UMC.Data.DataFactory.Instance().Config($"SITE_MIME_{site.Root}_LOGIN_HTML".ToUpper());
            if (htmlconfig != null)
            {
                htmlconfig.ConfKey = $"SITE_MIME_{newRoot}_LOGIN_HTML".ToUpper();
                UMC.Data.DataFactory.Instance().Put(htmlconfig);
            }

            site.Root = newRoot;
            site.Caption = config["Caption"];
            site.SiteKey = UMC.Data.Utility.IntParse(UMC.Data.Utility.Guid(newRoot, true).Value);
            DataFactory.Instance().Put(site);

            String webrkey = String.Format("images/{0}/{1}/{2}.png", site.Root, 1, 0);
            using (System.IO.Stream stream = typeof(WebServlet).Assembly
                                    .GetManifestResourceStream("UMC.ITME.Resources.app.png"))
            {
                UMC.Data.WebResource.Instance().Transfer(stream, webrkey);
            }

            this.Prompt("应用复制成功", false);
            this.Context.Send("Site.Config", true);
            this.Context.Response.Redirect(this.Context.Request.Model, this.Context.Request.Command, site.Root);
        }
        void CopyMime(String formt, String old, String root)
        {

            var oldKey = String.Format(formt, old).ToUpper();
            var newKey = String.Format(formt, root).ToUpper();

            var pconfig = UMC.Data.DataFactory.Instance().Config(oldKey);
            if (pconfig == null)
            {
                return;

            }
            var config = new Hashtable();
            var v = UMC.Data.JSON.Deserialize(pconfig.ConfValue?.UTF8()) as Hashtable;
            if (v != null)
            {
                config = v;
            }
            pconfig.ConfKey = newKey;
            UMC.Data.DataFactory.Instance().Put(pconfig);

            var feilds = config["Feilds"] as Hashtable;
            if (feilds != null && feilds.Count > 0)
            {
                var fd = feilds.Keys.Cast<String>().OrderBy(r => r).GetEnumerator();

                while (fd.MoveNext())
                {

                    var fconfig = UMC.Data.DataFactory.Instance().Config($"{oldKey}_{fd.Current}".ToUpper());
                    if (fconfig != null)
                    {
                        fconfig.ConfKey = $"{newKey}_{fd.Current}".ToUpper();
                        UMC.Data.DataFactory.Instance().Put(fconfig);
                    }
                }
            }

        }
        void Cert(Site site)
        {
            var ComboValue = UIDialog.AsyncDialog(this.Context, "Combo", g =>
           {
               var lic = License.GetLicense(site.MarketKey);

               var from = new Web.UIFormDialog() { Title = "市场应用许可证" };
               var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
               var json = UMC.ITME.Utility.Sign(new Uri(APIProxy.Uri, "Transfer").WebRequest(), secret).Post(new WebMeta("type", "Market", "LicenseCode", site.MarketKey).Put("ExpireTime", lic.ExpireTime), out var _);//.ReadAsString();
               var data = JSON.Deserialize<System.Collections.Hashtable>(json);

               if (data.ContainsKey("sign"))
               {
                   License.Put(site.MarketKey, data["sign"] as string);
               }
               this.Context.Request.Arguments["API"] = data["BuySrc"] as string;
               var Combo = data["Combo"] as Array;
               var style = new UIStyle();
               style.Name("icon").Color(0x09bb07).Size(84).Font("wdk");
               style.Name("title").Color(0x333).Size(20);
               style.BgColor(0xfafcff).Height(200).AlignCenter();
               var desc = new UMC.Web.WebMeta().Put("title", data["Desc"] ?? "应用配置证书订阅").Put("icon", data["Icon"] ?? "\uf085");
               from.Config.Put("Header", new UIHeader().Desc(desc, "{icon}\n{title}", style));


               from.AddTextValue().Put("所属应用", site.Caption).Put("证书过期", data["Expire"] as string).Put("续期方式", data["PeriodType"] as string);

               if (data.ContainsKey("BuySrc"))
               {
                   var f = from.AddRadio("订购套餐", "Combo");
                   var cl = Combo.Length;
                   for (var i = 0; i < cl; i++)
                   {
                       var hash = Combo.GetValue(i) as System.Collections.Hashtable;
                       f.Put(hash["Text"] as string, hash["Value"] as string, i == cl - 1);
                   }
                   from.Config.Put("Action", true);

                   from.Submit(data["Button"] as string ?? "确认订购");
               }
               else
               {
                   from.HideSubmit();
               }
               from.Add(UICell.UI('\uf19d', "开发者", data["Seller"] as string));
               from.Add(UICell.UI('\uf1e4', "服务电话", data["Tel"] as string, UIClick.Tel(data["Tel"] as string)));


               return from;
           });

            var src = this.AsyncDialog("API", r =>
            {
                this.Prompt("支付参数不正确，请联系官方");
            });
            this.Context.Response.Redirect(new Uri($"{src}&Combo={ComboValue}"));

        }
        void ApiSecure(Site site)
        {
            var req = this.Context.Request;
            var siteType = site.Type ?? 0;
            var lic = License.GetLicense($"Secure_{site.Root}");
            var apiSecure = this.AsyncDialog("ApiSecure", g =>
            {
                var ui = UISection.Create(new UITitle("攻击防护"));

                ui.AddCell("服务期限", Utility.Expire(lic.ExpireTime, "未开启"), new UIClick(req, g, "BuySrc"));
                ui.NewSection()
                .AddCell("请求网址最大长度", $"{site.ApiSecureUrlSize ?? 1500}", new UIClick(req, g, "ApiSecureUrlSize"))

                .AddCell("标头字段最大长度", $"{site.ApiSecureFieldSize ?? 500}", new UIClick(req, g, "ApiSecureFieldSize"))
                .AddCell("标头字段最多个数", $"{site.ApiSecureHeadCount ?? 30}个", new UIClick(req, g, "ApiSecureHeadCount"))
                .AddCell("提交内容最大字节", String.IsNullOrEmpty(site.ApiSecureBodySize) ? "未设置" : site.ApiSecureBodySize, new UIClick(req, g, "ApiSecureBodySize"))
                .NewSection().AddCell("请求内容超时", $"{site.ApiSecureBodyTimeOut ?? 300}s", new UIClick(req, g, "ApiSecureBodyTimeOut"))
                .AddCell("请求标头超时", $"{site.ApiSecureHeadTimeOut ?? 10}s", new UIClick(req, g, "ApiSecureHeadTimeOut"))
                .AddCell("响应最低网速", $"{site.ApiSecureNetworkSpeed ?? 100}B/s", new UIClick(req, g, "ApiSecureNetworkSpeed"))
                .AddCell("报警终端连接数", $"{site.ApiSecureConnections ?? 100}个", new UIClick(req, g, "ApiSecureConnections"));

                ui.NewSection().AddCell("防护检验周期", $"{site.ApiSecureTime ?? 60}s", new UIClick(req, g, "ApiSecureTime"))
                .AddCell("路径安全频次", $"{site.ApiSecureRepetitions ?? 30}", new UIClick(req, g, "ApiSecureRepetitions"))
                .AddCell("锁定攻击次数", $"{site.ApiSecureLockTimes ?? 5}", new UIClick(req, g, "ApiSecureLockTime"));
                ui.NewSection().Add(new UISwitch().Text("关闭人机效验").Selected((site.Type & 1024) > 0).Click(new UIClick(req, g, "Fingerprint"), new UIClick(req, g, "NotFingerprint")));
                ui.NewSection().Add(new UISwitch().Text("关闭攻击防护").Selected((site.Type & 8) > 0).Click(new UIClick(req, g, "ApiSecure"), new UIClick(req, g, "NotApiSecure")));

                ui.NewSection().AddCell("高频路径", new UIClick(req, "Model", "HighPath"));

                ui.SendTo(this.Context, "Site.Setting", "Site.License");

            });
            switch (apiSecure)
            {
                case "ApiSecureLockTime":
                    {
                        var ApiSecureLockTime = Utility.IntParse(this.AsyncDialog("ApiSecureLockTime", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureLockTimes ?? 5) { Title = "锁定攻击次数" };
                                         }), 5);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureLockTimes = ApiSecureLockTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;

                case "ApiSecureUrlSize":
                    {
                        var ApiSecureUrlSize = Utility.IntParse(this.AsyncDialog("ApiSecureUrlSize", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureRepetitions ?? 1500) { Title = "最大请求网址长度" };
                                         }), 1500);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureUrlSize = ApiSecureUrlSize });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureRepetitions":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureRepetitions", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureRepetitions ?? 30) { Title = "周期安全频次" };
                                         }), 15);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureRepetitions = ApiSecureTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureBodyTimeOut":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureBodyTimeOut", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureBodyTimeOut ?? 300) { Title = "请求内容超时" };
                                         }), 300);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureBodyTimeOut = ApiSecureTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureHeadTimeOut":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureHeadTimeOut", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureHeadTimeOut ?? 10) { Title = "提交请求头超时" };
                                         }), 60);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureHeadTimeOut = ApiSecureTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureConnections":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureConnections", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureConnections ?? 100) { Title = "报警终端连接数" };
                                         }), 60);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureConnections = ApiSecureTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureBodySize":
                    {
                        var ApiSecureBodySize = this.AsyncDialog("ApiSecureBodySize", g =>
                                         {
                                             var dg = new UITextDialog(site.ApiSecureBodySize) { Title = "提交内容最大字节" };
                                             dg.Config.PlaceHolder("单位可以k或m");
                                             return dg;
                                         });

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureBodySize = ApiSecureBodySize });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureHeadCount":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureHeadField", g =>
                                          {
                                              return new UINumberDialog(site.ApiSecureHeadCount ?? 20) { Title = "标头字段最多个数" };
                                          }), 30);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureHeadCount = ApiSecureTime });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureFieldSize":
                    {
                        var ApiSecureHeadSize = Utility.IntParse(this.AsyncDialog("ApiSecureFieldSize", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureFieldSize ?? 500) { Title = "标头字段最大长度" };
                                         }), 500);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureFieldSize = ApiSecureHeadSize });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureNetworkSpeed":
                    {
                        var ApiSecureHeadSize = Utility.IntParse(this.AsyncDialog("ApiSecureNetworkSpeed", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureNetworkSpeed ?? 100) { Title = "响应最低网速" };
                                         }), 500);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureNetworkSpeed = ApiSecureHeadSize });

                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecureTime":
                    {
                        var ApiSecureTime = Utility.IntParse(this.AsyncDialog("ApiSecureTime", g =>
                                         {
                                             return new UINumberDialog(site.ApiSecureTime ?? 60) { Title = "防护检验周期" };
                                         }), 60);

                        DataFactory.Instance().Put(new Site { Root = site.Root, ApiSecureTime = ApiSecureTime });
                        this.Context.Send("Site.Setting", true);
                    }
                    break;
                case "ApiSecure":
                    if ((site.Type & 8) > 0)
                        DataFactory.Instance().Put(new Site { Root = site.Root, Type = siteType ^ 8 });
                    return;
                case "NotApiSecure":
                    DataFactory.Instance().Put(new Site { Root = site.Root, Type = siteType | 8 });
                    return;

                case "NotFingerprint":
                    DataFactory.Instance().Put(new Site { Root = site.Root, Type = siteType | 1024 });
                    return;
                case "Fingerprint":
                    if ((siteType & 1024) > 0)
                        DataFactory.Instance().Put(new Site { Root = site.Root, Type = siteType ^ 1024 });
                    return;
                case "BuySrc":
                    var ComboValue = UIDialog.AsyncDialog(this.Context, "Combo", g =>
                   {

                       var from = new Web.UIFormDialog() { Title = "订阅应用安全防护" };
                       var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
                       var json = UMC.ITME.Utility.Sign(new Uri(APIProxy.Uri, "Transfer").WebRequest(), secret).Post(new WebMeta("type", "ApiSecure", "Code", site.Root).Put("ExpireTime", lic.ExpireTime), out var _);//.ReadAsString();
                       var data = JSON.Deserialize<System.Collections.Hashtable>(json);

                       if (data.ContainsKey("sign"))
                       {
                           this.Context.Send("Site.License", false);
                           License.Put($"Secure_{site.Root}", data["sign"] as string);
                       }
                       this.Context.Request.Arguments["API"] = data["BuySrc"] as string;
                       var Combo = data["Combo"] as Array;
                       var style = new UIStyle();
                       style.Name("icon").Color(0x09bb07).Size(84).Font("wdk");
                       style.Name("title").Color(0x333).Size(20);
                       style.BgColor(0xfafcff).Height(200).AlignCenter();
                       var desc = new UMC.Web.WebMeta().Put("title", data["Desc"] ?? "订阅应用安全防护").Put("icon", data["Icon"] ?? "\uf085");
                       from.Config.Put("Header", new UIHeader().Desc(desc, "{icon}\n{title}", style));


                       from.AddTextValue().Put("所属应用", site.Caption).Put("防护过期", data["Expire"] as string).Put("续期方式", data["PeriodType"] as string);

                       if (data.ContainsKey("BuySrc"))
                       {
                           var f = from.AddRadio("订购套餐", "Combo");
                           var cl = Combo.Length;
                           for (var i = 0; i < cl; i++)
                           {
                               var hash = Combo.GetValue(i) as System.Collections.Hashtable;
                               f.Put(hash["Text"] as string, hash["Value"] as string, i == cl - 1);
                           }
                           from.Config.Put("Action", true);

                           from.Submit(data["Button"] as string ?? "确认订购");
                       }
                       else
                       {
                           from.HideSubmit();
                       }
                       return from;
                   });

                    var src = this.AsyncDialog("API", r =>
                    {
                        this.Prompt("支付参数不正确，请联系官方");
                    });
                    this.Context.Response.Redirect(new Uri($"{src}&Combo={ComboValue}"));
                    break;
            }

        }
        void EditCert(Site site)
        {
            if (String.IsNullOrEmpty(site.MarketKey))
            {
                return;
            }
            var appId = UMC.Data.WebResource.Instance().Provider["appId"];

            var Seller = site.MarketKey.Split('_')[0];

            var lic = License.GetLicense(Seller);
            var request = this.Context.Request;
            var config = UIDialog.AsyncDialog(this.Context, "Settings", g =>
            {
                var from = new Web.UIFormDialog() { Title = "编辑证书" };
                from.Menu("输入", request.Model, request.Command, new WebMeta(request.Arguments).Put(g, "Text"));
                var style = new UIStyle();
                style.Name("icon").Color(0xffbe00).Size(84).Font("wdk");
                style.Name("title").Color(0x333).Size(16);
                style.BgColor(0xfafcff).Height(180).AlignCenter();

                from.AddHeader(new UIHeader().Desc(new UMC.Web.WebMeta().Put("title", "配置市场应用需要证书").Put("icon", "\uea05"), "{icon}\n{title}", style));
                from.Add(new UIQRCode($"https://api.apiumc.com/UMC/Platform/EditCert/{appId}/{Seller}"));
                from.AddFooter("请应用开发者用ITME App扫一扫，生成证书，再点击下一步", "Settings", "YES");

                from.Submit("下一步", $"{request.Model}.{request.Command}");
                return from;
            });
            var content = UIDialog.AsyncDialog(this.Context, "Content", r =>
            {
                if (config == "Text")
                {
                    var from = new Web.UIFormDialog() { Title = "编辑证书" };
                    from.AddTextarea("证书内容", "Content", String.Empty).Put("Pre", true).Put("Rows", 10);
                    from.Submit("核验证书", $"{request.Model}.{request.Command}");
                    return from;
                }
                else
                {
                    return UIDialog.ReturnValue(new Uri($"https://wdk.oss-accelerate.aliyuncs.com/TEMP/EditCert/{appId}_{Seller}.lic").WebRequest().Get(out var _));

                }

            });
            if (String.IsNullOrEmpty(content))
            {
                this.Prompt("获取证书失败");
            }
            if (License.Put(Seller, content))
            {
                this.Context.Send(false);
                this.Prompt("证书导入成功");
            }
            else
            {
                this.Prompt("获取证书失败,请确认证书是否一致");
            }
        }
        public override void ProcessActivity(WebRequest request, WebResponse response)
        {

            this.Context.Client.Context.NotCounted();
            var Key = this.AsyncDialog("Key", g =>
            {
                var form = request.SendValues ?? new WebMeta();
                var limit = form["limit"] ?? "none";
                switch (limit)
                {
                    case "PC":
                        {

                            var siteGroups = DataFactory.Instance().SiteGroup().ToList();//.OrderBy(r => r.Seq ?? 0);
                            siteGroups.Add(new SiteGroup { Caption = "我的应用", Key = 0, Seq = 0 });
                            var GroupKey = Utility.IntParse(this.AsyncDialog("GroupKey", "-1"), -1);
                            var sts = new System.Data.DataTable();
                            sts.Columns.Add("id");
                            sts.Columns.Add("name");
                            sts.Columns.Add("root");
                            sts.Columns.Add("domain");
                            sts.Columns.Add("module");
                            sts.Columns.Add("auth");
                            sts.Columns.Add("log");
                            sts.Columns.Add("group");
                            var Keyword = form["Keyword"];
                            var group = new SiteGroup { Caption = "我的应用", Key = 0, Seq = 0 };
                            var ds = DataFactory.Instance().Site();
                            if (GroupKey > -1 && String.IsNullOrEmpty(Keyword))
                            {
                                if (form.ContainsKey("module"))
                                {
                                    ds = ds.Where(r => (r.GroupKey ?? 0) == GroupKey && (r.IsModule ?? false) == false).ToArray();

                                }
                                else
                                {
                                    ds = ds.Where(r => (r.GroupKey ?? 0) == GroupKey).ToArray();
                                }

                            }
                            if (String.IsNullOrEmpty(Keyword) == false)
                            {

                                ds = ds.Where(r => r.Caption.Contains(Keyword) || r.Root.Contains(Keyword) || r.Domain.Contains(Keyword)).Where(r => r.Flag != -1).OrderBy(r => r.Caption).ToArray();
                            }
                            else
                            {

                                ds = ds.Where(r => r.Flag != -1).OrderBy(r => r.Seq ?? 1000).ToArray();
                            }
                            switch (request.SendValues?.Get("field") ?? String.Empty)
                            {
                                case "root":
                                    ds = (String.Equals(request.SendValues?.Get("sort"), "desc") ? ds.OrderByDescending(s => s.Root) : ds.OrderBy(s => s.Root)).ToArray();
                                    break;
                                case "title":
                                    ds = (String.Equals(request.SendValues?.Get("sort"), "desc") ? ds.OrderByDescending(s => s.Caption) : ds.OrderBy(s => s.Caption)).ToArray();
                                    break;
                                case "auth":
                                    ds = (String.Equals(request.SendValues?.Get("sort"), "desc") ? ds.OrderByDescending(s => s.AuthType) : ds.OrderBy(s => s.AuthType)).ToArray();
                                    break;
                                default:

                                    break;
                            }
                            foreach (var d in ds)
                            {
                                var dtype = "桌面展示";
                                if (d.IsModule == true)
                                {
                                    dtype = "应用隐藏";
                                }
                                else if (d.IsDesktop ?? false == false)
                                {
                                    dtype = "桌面展示";
                                }
                                var gp = siteGroups.FirstOrDefault(r => r.Key == d.GroupKey) ?? group;
                                var Domain = d.Domain ?? "";

                                var domains = Domain.Split(new char[] { ',', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                                sts.Rows.Add(d.SiteKey ?? UMC.Data.Utility.IntParse(UMC.Data.Utility.Guid(d.Root, true).Value), d.Caption, d.Root, domains.Length > 0 ? (domains.Length > 1 ? "多例均衡" : (domains[0].StartsWith("file:") ? "文件系统" : domains[0])) : "错误", dtype, d.AuthType ?? Web.WebAuthType.All, d.IsDebug == true ? "开启" : "未开启", gp.Caption);

                            }
                            // }

                            var rdata = new WebMeta().Put("data", sts);
                            response.Redirect(request.IsMaster ? rdata.Put("IsMaster", true) : rdata);
                        }
                        break;
                    default:
                        {
                            var title = UITitle.Create();

                            title.Title = "应用管理";

                            var ds = DataFactory.Instance().Site();

                            var Keyword = form["Keyword"];
                            if (String.IsNullOrEmpty(Keyword) == false)
                            {

                                ds = ds.Where(r => r.Caption.Contains(Keyword) || r.Root.Contains(Keyword) || r.Domain.Contains(Keyword)).Where(r => r.Flag != -1).OrderBy(r => r.Caption).ToArray();
                            }
                            else
                            {

                                ds = ds.Where(r => r.Flag != -1).OrderBy(r => r.Seq ?? 1000).ToArray();
                            }

                            var ui = UISection.Create(new UIHeader().Search("搜索"), title);
                            var webr = UMC.Data.WebResource.Instance();

                            foreach (var d in ds)
                            {
                                var cell = new UIImageTextValue(webr.ImageResolve(request.Url, d.Root, "1", 4), d.Caption, d.Root);
                                cell.Click(new UIClick(request, g, d.Root));

                                cell.Style.Name("image-width", 72);
                                cell.Style.Name("image-radius", 10);
                                ui.Add(cell);
                            }
                            if (ds.Length == 0)
                            {
                                if (String.IsNullOrEmpty(Keyword))
                                {
                                    var desc = new UIDesc("未有的应用，请发布新应用");
                                    desc.Put("icon", "\uf016").Format("desc", "{icon}\n{desc}");
                                    desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
                                    ui.Add(desc);
                                }
                                else
                                {
                                    var desc = new UIDesc($"未搜索到“{Keyword}”相关发布的应用");
                                    desc.Put("icon", "\uf016").Format("desc", "{icon}\n{desc}");
                                    desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
                                    ui.Add(desc);
                                }
                            }
                            if (request.IsMaster)
                            {
                                ui.UIFootBar = new UIFootBar() { IsFixed = true };
                                ui.UIFootBar.AddText(new UIEventText("网关服务").Click(new UIClick(request.Model, "Server")),
                                 new UIEventText("发布新应用").Click(new UIClick(request.Model, "Setup")).Style(new UIStyle().BgColor()));
                            }
                            ui.SendTo(this.Context, $"{request.Model}.{request.Command}");
                        }
                        break;
                }
            });

            var site = DataFactory.Instance().Site(Key);

            var ms = request.SendValues ?? request.Arguments;
            var Model = this.AsyncDialog("Model", g =>
            {
                if (ms.ContainsKey("limit") == false)
                {
                    if (site == null)
                    {
                        site = DataFactory.Instance().Site(UMC.Data.Utility.IntParse(Key, 0));
                        if (site != null)
                        {
                            request.Arguments.Put("Key", site.Root);
                        }
                    }
                }
                var isFile = SiteConfig.Config(site.Domain).Any(r => r.StartsWith("file://"));

                var IsProxy = SiteConfig.Config(site.AuthConf).Contains("*");
                var IsShow = ms["Show"] == "true";
                if (IsProxy == false)
                {
                    IsShow = true;
                }
                if (isFile)
                {
                    IsShow = false;
                }
                var title = UITitle.Create();

                title.Title = "应用配置";

                var IsLicense = false;
                var appId = UMC.Data.WebResource.Instance().Provider["appId"];
                var ui = UISection.Create(title);
                if (String.IsNullOrEmpty(site.MarketKey) == false)
                {
                    var lic = License.GetLicense(site.MarketKey.Split('_')[0]);
                    IsLicense = lic.ExpireTime < Utility.TimeSpan();
                }
                var editCert = new UIClick(request, g, "EditCert");
                var imageTextView = new UMC.Web.UI.UIImageTextValue(Data.WebResource.Instance().ImageResolve(request.Url, site.Root, "1", 4, $"_t={site.ModifyTime}"), "", "图标");
                imageTextView.Style.Name("image-width", "100");
                imageTextView.Click(new UIClick(request, g, "Image"));

                ui.Add(imageTextView);

                ui.AddCell("应用标识", site.Root, new UIClick(request, g, "Setting"))

                 .AddCell("应用名称", site.Caption, new UIClick(request, g, "Caption"));
                var slic = License.GetLicense($"Secure_{site.Root}");
                ui.NewSection().AddCell("攻击防护", Utility.Expire(slic.ExpireTime, "未开启"), new UIClick(request, g, site.Root, "Model", "ApiSecure"));



                var domains = site.Domain.Split(new char[] { ',', '\n' }, StringSplitOptions.RemoveEmptyEntries);

                if (isFile)
                {
                    ui.NewSection().AddCell("负载网址", domains.Length > 0 ? (domains.Length > 1 ? "多例均衡" : (domains[0].StartsWith("file:") ? "文件系统" : domains[0])) : "错误", new UIClick(request, g, "Domain"));
                }
                else
                {
                    ui.NewSection().AddCell("负载网址", domains.Length > 0 ? (domains.Length > 1 ? "多例均衡" : (domains[0].StartsWith("file:") ? "文件系统" : domains[0])) : "错误", new UIClick(request, g, "Domain"))

                    .AddCell("请求配置", String.IsNullOrEmpty(site.HeaderConf) ? "未设置" : "已设置", IsLicense ? editCert : new UIClick(request, g, "HeaderConf"))
                    .AddCell("动静分离", String.IsNullOrEmpty(site.StaticConf) ? "未设置" : "已设置", new UIClick(request, g, "StaticConf"));
                    //   .AddCell("日志参数", String.IsNullOrEmpty(site.LogConf) ? "未设置" : "已设置", new UIClick(request, g, "LogConf"));
                    if (IsShow)
                    {
                        ui.NewSection().AddCell("桌面授权", "", new UIClick(request, g, site.Root, "Model", "Auth"))
                       .AddCell("应用安全码", new UIClick(request, g, "AppSecret"));
                    }
                }

                var imageUI = ui.NewSection().AddCell("图片处理", "配置", new UIClick(request, g, "ImagesConf"));


                var imagePaths = SiteConfig.Config(site.ImagesConf);
                foreach (var key in imagePaths)
                {
                    imageUI.AddCell(key, new UIClick(request.Model, "ConfImage", String.Format("SITE_IMAGE_CONFIG_{0}{1}", site.Root, MD5(key as string)).ToUpper()));
                }

                var ui2 = ui.NewSection().AddCell("应用目录", "配置", new UIClick(request, g, "Path"));


                var path = new Hashtable();

                if (String.IsNullOrEmpty(site.SubSite) == false)
                {
                    var v = UMC.Data.JSON.Deserialize(site.SubSite) as Hashtable;
                    if (v != null)
                    {
                        path = v;
                    }
                }
                var pem = path.GetEnumerator();
                while (pem.MoveNext())
                {
                    var pcell = UICell.Create("UI", new WebMeta().Put("value", pem.Value.ToString(), "text", pem.Key.ToString()));
                    ui2.Delete(pcell, new UIEventText("移除").Click(new UIClick(request, g, pem.Key.ToString())));
                }

                var hosts = DataFactory.Instance().Hosts(new StringValue(site.Root));
                ui2 = ui.NewSection().AddCell("应用域名", "配置", new UIClick(request, g, "Host"));


                var home = UMC.Data.WebResource.Instance().WebDomain();
                if (home == "localhost")
                {
                    var v = UICell.UI('\uf015', $"{site.Root}{WebServlet.DomainUnion}[主域名]", "主域名未配置", new UIClick(request.Model, "Server"));
                    v.Style.Name("value").Color(0xc00);
                    ui2.Add(v);
                }
                else
                {
                    ui2.AddCell('\uf015', $"[{site.Root}{WebServlet.DomainUnion}{home}]", "", new UIClick(request.Model, "Server", "Model", "CSR", "Domain", $"{site.Root}.{home}"));
                }
                var isHostProxy = false;
                foreach (var h in hosts)
                {
                    var Scheme = String.Empty;
                    switch (h.Scheme ?? 0)
                    {
                        case 2:
                            Scheme = "Https";
                            break;
                    }
                    var pcell = UICell.UI(h.IsAuthModel == true ? '\uf13e' : '\uf0c1', h.Host.ToString(), Scheme, new UIClick(request.Model, "Server", "Model", "CSR", "Domain", h.Host.Span.UTF8()));
                    ui2.Delete(pcell, new UIEventText("移除").Click(new UIClick(request, g, h.Host.Span.UTF8())));
                    if (h.IsAuthModel == true)
                    {
                    }
                    else
                    {
                        isHostProxy = true;
                    }

                }

                if (isHostProxy && IsShow)
                {
                    var hm = "不切换";
                    switch (site.HostModel ?? HostModel.None)
                    {
                        case HostModel.Login:
                            hm = "登录页切换";
                            break;
                        case HostModel.Check:
                            hm = "浏览器中切换";
                            break;
                        case HostModel.Disable:
                            hm = "全域名切换";
                            break;
                    }

                    ui2 = ui2.NewSection().AddCell("切换认证", hm, new UIClick(request, g, "HostModel"));
                    ui2.AddCell("切换地址", "配置", new UIClick(request, g, "RedirectPath"));
                    var redPaths = SiteConfig.Config(site.RedirectPath);
                    foreach (var key in redPaths)
                    {
                        ui2.AddCell(key, new UIClick(request.Model, "Conf", String.Format("SITE_JS_CONFIG_{0}{1}", site.Root, MD5(key as string)).ToUpper()));
                    }
                    ui2.Header.Put("text", "反代域名设置");
                }
                if (IsShow)
                {

                    ui2 = ui.NewSection().AddCell("应用管理员", "配置", new UIClick(request, g, "Admin"));

                    var users = UMC.Data.DataFactory.Instance().Users(site.SiteKey.Value, UMC.Security.Membership.AdminRole);//.Select(r => r.user_id.Value);

                    if (users.Length > 0)
                    {
                        foreach (var key in users)
                        {
                            var pcell = UICell.UI('\uf007', key.Alias, "", new UIClick("Account", "Staff", key.Username));
                            ui2.Delete(pcell, new UIEventText("移除").Click(new UIClick(request.Model, "User", "Setting", "Rolename", "Rolename", UMC.Security.Membership.AdminRole, "Id", key.Id.Value.ToString(), "Site", site.SiteKey.ToString())));
                        }

                    }

                    if (UserModel.Bridge == site.UserModel && site.AuthConf == "#")
                    {
                        ui.NewSection()
                         .AddCell("许可路径", "轻应用模式", new UIClick(request, g, "AuthConf"))
                                         .AddCell("云模块加载", "配置", new UIClick(request.Model, "UMC", site.Root));
                    }
                    else
                    {
                        ui.NewSection()
                                .AddCell("许可路径", String.IsNullOrEmpty(site.AuthConf) ? "未设置" : (IsProxy ? "代理转发" : "已设置"), new UIClick(request, g, "AuthConf"))
                          .AddCell("应用时效", String.Format("{0}s:{1}m", site.Timeout ?? 100, site.AuthExpire ?? 30), new UIClick(request, g, "Timeout"));
                    }


                    ui2 = ui.NewSection().AddCell("追加脚本", "配置", new UIClick(request, g, "AppendJSConf"));


                    var jsPaths = SiteConfig.Config(site.AppendJSConf);
                    foreach (var key in jsPaths)
                    {
                        ui2.AddCell(key, new UIClick(request.Model, "Conf", String.Format("SITE_JS_CONFIG_{0}{1}", site.Root, MD5(key as string)).ToUpper()));
                    }

                    ui2 = ui.NewSection().AddCell("请求触发", String.IsNullOrEmpty(site.LogoutPath) ? "未设置" : "已设置", new UIClick(request, g, "LogoutPath"))
                    .AddCell("响应处理", "配置", new UIClick(request, g, "ResBlockPage"));


                    ui2 = ui.NewSection().AddCell("域名清洗", String.IsNullOrEmpty(site.HostReConf) ? "未设置" : "已设置", IsLicense ? editCert : new UIClick(request, g, "HostReConf"));


                    ui2.AddCell("共享会话", String.IsNullOrEmpty(site.OutputCookies) ? "未设置" : "已设置", new UIClick(request, g, "OutputCookie"));

                    var m = "标准模式";
                    switch ((site.UserModel ?? UserModel.Standard))
                    {
                        case UserModel.Bridge:
                            m = "桥接模式";
                            break;
                        case UserModel.Share:
                            m = "共享模式";
                            break;
                        case UserModel.Quote:
                            m = "引用模式";
                            break;
                        case UserModel.Check:
                            m = "自主检测";
                            break;
                        case UserModel.Checked:
                            m = "自动检测";
                            break;
                    }

                    ui.NewSection().AddCell("账户对接模式", m, new UIClick(request, g, "UserModel"));


                    ui.NewSection().AddCell("账户登录接口", IsLicense ? editCert : new UIClick(request.Model, "Mime", String.Format("{0}_Login", site.Root)));

                    ui.NewSection().AddCell("密码托管接口", IsLicense ? editCert : new UIClick(request.Model, "Mime", String.Format("{0}_Update", site.Root)));

                    ui.NewSection().AddCell("账户检测接口", IsLicense ? editCert : new UIClick(request.Model, "Mime", String.Format("{0}_Check", site.Root)));
                }
                //

                if (String.IsNullOrEmpty(site.MarketKey))
                {
                    ui.NewSection().AddCell("出售此配置", "上架到应用市场", new UIClick(request, g, "Market"));
                }
                else
                {

                    var lic = License.GetLicense(site.MarketKey);
                    ui.NewSection().AddCell("许可证过期", Utility.Expire(Utility.TimeSpan(), lic.ExpireTime, "已过期"), new UIClick(request, g, "Cert"));
                }

                ui.NewSection().AddCell("联系官方", "让天才工程师为你配置", new UIClick("System", "License", "Contact"));

                if (IsShow)
                {
                    ui.UIFootBar = new UIFootBar() { IsFixed = true };
                    ui.UIFootBar.AddText(new UIEventText("应用设置").Click(new UIClick(request, g, "Setting")),// request.Model, "App").Send("Key", site.Root, "Model", "Setting")),
                     new UIEventText("重新加载").Click(new UIClick(request, g, "Reload")).Style(new UIStyle().BgColor()));


                }
                else
                {
                    ui.UIFootBar = new UIFootBar() { IsFixed = true };
                    ui.UIFootBar.AddText(new UIEventText("网关登录配置").Click(UIClick.Query(new WebMeta().Put("Show", "true"))),
                     new UIEventText("重新加载").Click(new UIClick(request, g, "Reload")).Style(new UIStyle().BgColor()));

                }
                ui.SendTo(this.Context, $"{request.Model}.{request.Command}", "Site.Config", "System.Image");
            });

            if (request.IsMaster == false)
            {
                var rols = UMC.Data.DataFactory.Instance().Roles(this.Context.Token.UserId.Value, site.SiteKey.Value);
                if (rols.Contains(UMC.Security.Membership.AdminRole) == false)
                {
                    response.Redirect(request.Model, "App", site.Root);
                }

            }
            switch (Model)
            {
                case "ApiSecure":
                    this.ApiSecure(site);
                    break;
                case "HighPath":
                    this.HighFrequency(site);
                    break;
                case "Admin":
                    this.Admin(site);
                    break;
                case "GroupKey":
                    this.GroupKey(site);
                    break;
                case "ResBlockPage":
                    this.ResBlockPage(site);
                    break;
                case "EditCert":
                    EditCert(site);
                    break;
                case "Cert":
                    Cert(site);
                    break;
                case "Market":
                    Market(site);
                    break;
                case "Image":

                    DataFactory.Instance().Put(new Site
                    {
                        ModifyTime = Utility.TimeSpan(),
                        Root = site.Root
                    });
                    response.Redirect("System", "Image", new WebMeta().Put("id", site.Root).Put("index", "1"), true);
                    break;
                case "HostModel":
                    SetHostModel(site);
                    break;
                case "Copy":
                    if (request.IsMaster == false)
                    {
                        this.Prompt("复制应用需要管理员权限");
                    }
                    this.Copy(site);
                    break;
                case "Auth":
                    if (request.IsMaster == false)
                    {
                        this.Prompt("需要管理员权限");
                    }
                    response.Redirect("Settings", "AuthKey", new WebMeta().Put("Key", $"Desktop/{site.Root}"), true);
                    break;
                case "Quote":
                    this.Quote(site);
                    break;
                case "Share":
                    this.Share(site);
                    break;
                case "UserModel":
                    UseModel(site);
                    break;
                case "Caption":
                    this.Caption(site);
                    break;
                case "Timeout":
                    this.TimeOut(site);
                    break;
                case "ImagesConf":
                    this.ImagesConf(site);
                    break;
                case "AppendJSConf":
                    this.AppendJSConf(site);
                    break;
                case "HostReConf":
                    this.HostReConf(site);
                    break;
                case "LogoutPath":
                    this.LogoutPath(site);
                    break;
                case "Setting":
                    this.Setting(site);

                    break;
                case "AppSecret":
                    this.AppSecret(site);
                    break;
                case "LogConf":
                    this.LogConf(site);
                    break;
                case "Account":
                    this.Account(site);
                    break;
                case "OutputCookie":
                    this.OutputCookie(site);
                    break;
                case "Path":
                    this.Path(site);
                    break;
                case "Host":
                    this.Host(site);
                    break;
                case "Domain":
                    this.Domain(site);
                    break;
                case "Delete":
                    if (request.IsMaster == false)
                    {
                        this.Prompt("移除应用需要管理员权限");
                    }
                    this.Delete(site);
                    break;
                case "Reload":
                    DataFactory.Instance().Delete(new SiteConfig { Root = site.Root });
                    this.Prompt("重新加载已经就位");
                    break;
                case "HeaderConf":
                    this.HeaderConf(site);
                    break;
                case "AuthConf":
                    this.AuthConf(site);
                    break;
                case "RedirectPath":
                    this.RedirectPath(site);
                    break;
                case "StaticConf":
                    this.StaticConf(site);
                    break;
                default:
                    if (Model.StartsWith("/"))
                    {
                        var path = new Hashtable();

                        if (String.IsNullOrEmpty(site.SubSite) == false)
                        {
                            var v = UMC.Data.JSON.Deserialize(site.SubSite) as Hashtable;
                            if (v != null)
                            {
                                path = v;
                            }
                        }
                        path.Remove(Model);

                        DataFactory.Instance().Put(new Site { Root = site.Root, SubSite = UMC.Data.JSON.Serialize(path) });
                    }
                    else
                    {

                        DataFactory.Instance().Delete(new SiteHost { Host = new StringValue(Model) });
                    }

                    break;
            }



        }
        private void Admin(Site site)
        {
            var username = this.AsyncDialog("Admin", "Settings", "SelectUser");
            var user = UMC.Data.DataFactory.Instance().User(username);

            if (user != null)
            {
                UMC.Data.DataFactory.Instance().Put(new UserToRole
                {
                    Rolename = UMC.Security.Membership.AdminRole,
                    Site = site.SiteKey,
                    user_id = user.Id.Value,

                });
            }
            this.Context.Send("Site.Config", true);
        }
        private void Host(Site site)
        {
            var host = UIDialog.AsyncDialog(this.Context, "Setting", g =>
            {
                var from = new Web.UIFormDialog() { Title = "应用域名" };
                from.AddText("域名", "Setting", String.Empty);
                from.AddRadio("支持协议", "Scheme").Put("Http", "1", true).Put("Https", "2", true);//.Put("Http和Https", "0", true);
                from.AddCheckBox("", "IsAuth", "no").Put("启用身份体系", "Yes");
                from.Submit("确认", "Site.Config");
                return from;
            });
            if (System.Text.RegularExpressions.Regex.IsMatch(host, @"^([a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z0-9]{1,6}$") == false)
            {
                this.Prompt("域名格式不正确");
            }
            var hostValue = new StringValue(host);
            var h = DataFactory.Instance().Host(hostValue);
            if (h != null && String.Equals(h.Root.Span.UTF8(), site.Root) == false)
            {
                this.Prompt("此域名已经绑定其他应用");
            }
            DataFactory.Instance().Put(new SiteHost
            {
                Root = new StringValue(site.Root.UTF8()),
                Scheme = UMC.Data.Utility.IntParse(this.AsyncDialog("Scheme", "0"), 0),
                IsAuthModel = this.AsyncDialog("IsAuth", "0").Contains("Yes"),
                Host = new StringValue(host),
            }); ;

            this.Context.Send("Site.Config", true);
        }

        private void Domain(Site site)
        {
            var Setting = this.AsyncDialog("Setting", g =>
            {

                var from2 = new UIFormDialog() { Title = "负载网址" };
                if (String.IsNullOrEmpty(site.MarketKey) == false)
                {
                    var lic = License.GetLicense(site.MarketKey.Split('_')[0]);
                    from2.Add(UICell.UI("编辑证书", Utility.Expire(Utility.TimeSpan(), lic.ExpireTime, "已过期"), new UIClick(this.Context.Request, "Model", "EditCert")));
                }

                from2.AddText("负载域名", "Host", site.Host).PlaceHolder("默认取反代的域名").NotRequired();
                from2.AddRadio("均衡策略", "SLB")
                .Put("随机", "0", (site.SLB ?? 0) == 0)
                .Put("IP", "1", site.SLB == 1)
                .Put("Cookie", "2", site.SLB == 2);

                from2.AddTextarea("网址", "Domain", site.Domain).Put("Rows", 10).Put("Pre", true);//.PlaceHolder("服务网址");

                from2.AddFooter("后缀[0-9]表示负载均衡权重参数，后缀@user表示用户灰度");

                from2.Submit("确认", "Site.Config");
                return from2;
            });


            var Domain = Setting["Domain"];
            var doms = Domain.Split(',', '\n');
            var IsOk = false;
            foreach (var v in doms)
            {
                if (v.StartsWith("http://") || v.StartsWith("https://") || v.StartsWith("file://") || v.StartsWith("unix://"))
                {
                    IsOk = true;
                }
            }
            if (IsOk == false)
            {
                this.Prompt("请输入正确的网址");
            }
            var host = Setting["Host"] ?? String.Empty;
            if (String.IsNullOrEmpty(host) == false)
            {
                switch (host)
                {
                    case "*":
                        break;
                    case "none":
                        host = String.Empty;
                        break;
                    default:
                        if (System.Text.RegularExpressions.Regex.IsMatch(host, @"^([a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z0-9]{1,6}$") == false)
                        {
                            this.Prompt("负载域名格式不正确");
                        }

                        break;
                }
            }
            DataFactory.Instance().Put(new Site
            {
                Root = site.Root,
                Domain = Domain,
                Host = host,
                SLB = UMC.Data.Utility.IntParse(Setting["SLB"], 0)
            }); ;
            this.Context.Send("Site.Config", true);
        }
        private void LogConf(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "日志参数" };
                from.AddTextarea("参数", "LogConf", site.LogConf).Put("Pre", true).PlaceHolder("日志参数").Put("Rows", 10).NotRequired();
                from.AddFooter("默认获取Cookie值,以“:”开始表示获取请求Header值,以“:”结尾表示获取响应的Header值,多项用换行分割");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Key = config["LogConf"] ?? String.Empty;

            DataFactory.Instance().Put(new Site { Root = site.Root, LogConf = Key });

            this.Context.Send("Site.Config", true);
        }
        private void RedirectPath(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "切换地址" };
                from.AddTextarea("切换地址", "RedirectPath", site.RedirectPath).Put("Pre", true).PlaceHolder("路径配置格式").Put("Rows", 6).NotRequired();

                from.AddFooter("多项用换行、空格或逗号分割，支持“*”前后取配");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Key = config["RedirectPath"] ?? String.Empty;
            if (String.Equals("none", Key))
            {
                Key = String.Empty;
            }

            DataFactory.Instance().Put(new Site { Root = site.Root, RedirectPath = Key });

            this.Context.Send("Site.Config", true);
        }
        private void AuthConf(Site site)
        {
            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "许可路径" };
                from.AddTextarea("许可路径", "AuthConf", site.AuthConf).Put("Pre", true).PlaceHolder("路径配置格式").Put("Rows", 6).NotRequired();

                from.AddFooter("多项用换行、空格或逗号分割，支持“*”前后取配,当单行只有“*”，则表示只启用应用代理转发，关闭网关登录功能");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Key = config["AuthConf"] ?? String.Empty;
            if (String.Equals("none", Key))
            {
                Key = String.Empty;
            }

            DataFactory.Instance().Put(new Site { Root = site.Root, AuthConf = Key });

            this.Context.Send("Site.Config", true);
        }
        private void AppendJSConf(Site site)
        {

            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "追加脚本的路径" };

                from.AddTextarea("页面路径", "AppendJSConf", site.AppendJSConf).Put("Pre", true).PlaceHolder("路径配置格式").Put("Rows", 6).NotRequired();

                from.AddFooter("多项用换行、空格或逗号分割");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Key = config["AppendJSConf"] ?? String.Empty;

            DataFactory.Instance().Put(new Site { Root = site.Root, AppendJSConf = Key });

            this.Context.Send("Site.Config", true);
        }
        private void ImagesConf(Site site)
        {

            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "处理图片路径" };

                from.AddTextarea("触发路径", "ImagesConf", site.ImagesConf).Put("Pre", true).PlaceHolder("路径配置格式").Put("Rows", 6).NotRequired();

                from.AddFooter("多项用换行、空格或逗号分割");
                from.Submit("确认", "Site.Config");
                return from;
            });
            var Key = config["ImagesConf"] ?? String.Empty;

            DataFactory.Instance().Put(new Site { Root = site.Root, ImagesConf = Key });

            this.Context.Send("Site.Config", true);
        }

        private void StaticConf(Site site)
        {

            var config = this.AsyncDialog("Config", g =>
            {
                var from = new Web.UIFormDialog() { Title = "动静分离" };
                from.AddTextarea("分离路径", "StaticConf", site.StaticConf).Put("Pre", true).Put("Rows", 10).PlaceHolder("只有路径，则表示清除默认分离的配置").NotRequired();

                from.Submit("确认", "Site.Config");
                from.AddFooter("默认对gif、ico、svg、bmp、png、jpg、jpeg、css、less、sass、scss、js、webp、jsx、coffee、ts、ttf、woff、woff2、wasm类型文件进行静态分离，分离参数all、user、 one、[num]");

                return from;
            });
            var Key = config["StaticConf"] ?? String.Empty;


            DataFactory.Instance().Put(new Site { Root = site.Root, StaticConf = Key });

            this.Context.Send("Site.Config", true);
        }

    }
}